/**
 * @file s_calibration.c
 * @brief 
 * @author xuesong (wenshaoliu@foxmail.com)
 * @version 1.0
 * @date 2023-12-11
 * 
 * @copyright Copyright (c) 2023  by xuesong
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2023-12-11     <td>1.0     <td>xuesong   <td>内容
 * </table>
 */
#include "s_calibration.h"
#include "user_prcess.h"
#include "Display.h"
#include "CoffeeHandleMode.h"
#include "s_weight.h"
#include "UserKvSave.h"
//----------------------------------------------------------
uint8_t FindOffTimeIndex(uint16_t times)
{
    uint8_t i = 0;
    for(;i<COFFEE_OFF_TIME_INDEX;i++)
    {
        if(times <= COFFEE_OFF_TIME[i])
            break;
    }
    if(i >= COFFEE_OFF_TIME_INDEX)
        i = 1;
    return i;
}
//----------------------------------------------------------
void Fun_Process_Calibration(KeyStatus_t key)
{
    static uint8_t index = 0;
    int32_t subAdc = 0;
    uint32_t standWeight = 0;
    uint64_t    tempSubAdc;
    uint8_t calIndex = 0;               //标定次序
    if(!(UserProcess.ProcessFlag.flagBit.run))
    {
        UserProcess.ProcessFlag.flagBit.run = TRUE;
        if(UserProcess.ProcessFlag.flagBit.UserCalib)
            SwitchUserSubProcess(D_CAL_SET);
        else
            SwitchUserSubProcess(D_CAL_SELET_WTrang);
    }
    if(!UserProcess.ProcessFlag.flagBit.Subrun)
    {
        userAdcStruct.Flag.Bit.resetFilter = true;
        userAdcStruct.Flag.Bit.lock = false;
        UserProcess.subProcessHalfSec = 0;
        LOG("cal step = %d\r\n",UserProcess.subProcess);
    }
    switch (UserProcess.subProcess)
    {
        case    D_CAL_SET:
                {
                    if(!UserProcess.ProcessFlag.flagBit.Subrun)
                    {
                        UserProcess.ProcessFlag.flagBit.Subrun = true;
                        displayClrBuf(&DisplayData);
                        osal_memcpy(DisplayData.numberDataMidle,"  SET",5);
                        if(coffeMacInfor.Mode != COFFE_AtuoTare)
                            DisplayCoffeTime(coffeWeightAndTimer.TimerMs);
                    }
                    if(!key.Cont.flagBit.Tare)
                    {
                        if(UserProcess.subProcessHalfSec > 1)
                            SwitchUserSubProcess(D_CAL_SET_POWEROFF);
                    }
                }
                break;
        case    D_CAL_SET_POWEROFF:
                {
                    if(!UserProcess.ProcessFlag.flagBit.Subrun)
                    {
                        UserProcess.ProcessFlag.flagBit.Subrun = true;
                        index = FindOffTimeIndex(coffeMacInfor.AtuoOffTime);
                    }
                    if(key.ShortTrage.flagBit.Tare)
                    {
                        index++;
                        if(index >= COFFEE_OFF_TIME_INDEX)
                            index = 0;
                        // coffeMacInfor.AtuoOffTime = COFFEE_OFF_TIME[index];
                    }
                    subAdc = COFFEE_OFF_TIME[index];
                    if(key.LongTrage.flagBit.onOff)
                    {
                        coffeMacInfor.AtuoOffTime = subAdc;
                        SwitchUserSubProcess(D_CAL_SET_TimeFinish);
                    }else if(key.ShortTrage.flagBit.onOff){
                        SwitchUserSubProcess(D_CAL_SELET_WTrang);
                    }
                    displayClrBuf(&DisplayData);
                    osal_memcpy(DisplayData.numberDataLeft,"   T",4);
                    if(subAdc)
                        displayNumber2Number(subAdc/60,0,DisplayData.numberDataMidle,sizeof(DisplayData.numberDataMidle));
                    else
                        displayChar2Tuble(" OFF ",DisplayData.numberDataMidle,sizeof(DisplayData.numberDataMidle));
                }
                break;
        case    D_CAL_SET_TimeFinish:
                {
                    if(!UserProcess.ProcessFlag.flagBit.Subrun)
                    {
                        UserProcess.ProcessFlag.flagBit.Subrun = true;
                        // WriteCoffeeInfor(&coffeMacInfor);
                        coffeMacInfor.Flag.Bit.Change = true;
                        displayClrBuf(&DisplayData);
                        osal_memcpy(DisplayData.numberDataLeft,"   T",4);
                        displayChar2Tuble(" PASS",DisplayData.numberDataMidle,sizeof(DisplayData.numberDataMidle));
                    }
                    if(UserProcess.subProcessHalfSec > 4)
                    {
                        SwitchUseProcess(D_USER_PROCESS_ON);
                    }
                }
                break;
        case    D_CAL_SELET_WTrang:
                {
                    if(!UserProcess.ProcessFlag.flagBit.Subrun)
                    {
                        UserProcess.ProcessFlag.flagBit.Subrun = true;
                        if(ScaleInfor.WeightRangIndex >= SCALE_RANGE_CONT)
                            ScaleInfor.WeightRangIndex = 0;
                        ScaleInfor.MaxWeight = ScaleMaxWeight[ScaleInfor.WeightRangIndex];
                        ScaleInfor.MinWeight = ScaleMinWeight[ScaleInfor.WeightRangIndex];
                    }
                    if(key.ShortTrage.flagBit.Tare)
                    {
                        ScaleInfor.WeightRangIndex++;
                        if(ScaleInfor.WeightRangIndex >= SCALE_RANGE_CONT)
                            ScaleInfor.WeightRangIndex = 0;
                        ScaleInfor.MaxWeight = ScaleMaxWeight[ScaleInfor.WeightRangIndex];
                        ScaleInfor.MinWeight = ScaleMinWeight[ScaleInfor.WeightRangIndex];
                    }
                    if(key.ShortTrage.flagBit.onOff)
                    {
                        SwitchUserSubProcess(D_CAL_Zero);    
                        if(!UserProcess.ProcessFlag.flagBit.UserCalib)
                        {
                            if(ScaleInfor.MaxWeight < STAND_WEIGHT_POINT[CALIBRATE_PIONT - 1]) 
                                ScaleInfor.Calibration[CALIBRATE_PIONT - 1] = 0;                    //清除未标定标定值  
                        }               
                    }
                    displayClrBuf(&DisplayData);
                    displayChar2Tuble(" CEL",DisplayData.numberDataLeft,sizeof(DisplayData.numberDataLeft));
                    displayWeight(ScaleRang[ScaleInfor.WeightRangIndex],WEIGHT_UNIT_G);
                }
                break;
        case    D_CAL_Zero:
                {
                    if(!UserProcess.ProcessFlag.flagBit.Subrun)
                    {
                        UserProcess.ProcessFlag.flagBit.Subrun = true;
                        ScaleWeight.Flag.Bit.Calibr = true;
                        ScaleWeight.Flag.Bit.WtEnable = false;
                        ScaleWeight.DivisionAdc = STAND_WEIGHT_POINT[0]*7/STAND_WEIGHT_POINT[0];		//0.5D
                        ScaleWeight.DivisionAdc <<= 2;		                                            //默认值放大4倍
                        userAdcStruct.Flag.Bit.resetFilter = TRUE;
                    }
                    if(userAdcStruct.Flag.Bit.lock)
                    {
                        ScaleWeight.ZeroPointADC = userAdcStruct.DisplayAdc;
                        ScaleWeight.TarePointADC = ScaleWeight.ZeroPointADC;
                        ScaleWeight.Flag.Bit.ZeroOK = true;
                        SwitchUserSubProcess(D_CAL_POINT1);
                    }
                    displayClrBuf(&DisplayData);
                    if(UserProcess.ProcessFlag.flagBit.UserCalib)
                    {
                        displayChar2Tuble("   C",DisplayData.numberDataLeft,sizeof(DisplayData.numberDataLeft));
                        DisplayData.SymbleFlag.bit.negtiv = TRUE;
                    }
                    else
                        displayChar2Tuble(" CEL",DisplayData.numberDataLeft,sizeof(DisplayData.numberDataLeft));
                    displayChar2Tuble(" 2ER0",DisplayData.numberDataMidle,sizeof(DisplayData.numberDataMidle));
                }
                break;
        case    D_CAL_POINT1:
        case    D_CAL_POINT2:
        case    D_CAL_POINT3:
        case    D_CAL_POINT4:
                {
                    if(!UserProcess.ProcessFlag.flagBit.Subrun)
                    {
                        UserProcess.ProcessFlag.flagBit.Subrun = true;
                        if(UserProcess.subProcess == D_CAL_POINT1)
                            ScaleWeight.Flag.Bit.CalibrAtoZrEn = TRUE;
                        else
                            ScaleWeight.Flag.Bit.CalibrAtoZrEn = false;
                        calIndex = UserProcess.subProcess - D_CAL_POINT1;
                        userAdcStruct.Flag.Bit.resetFilter = TRUE;
                        if(ScaleInfor.MaxWeight < STAND_WEIGHT_POINT[calIndex])
                            SwitchUserSubProcess(D_CAL_Finish);
                    }
                    calIndex = UserProcess.subProcess - D_CAL_POINT1;
                    standWeight = STAND_WEIGHT_POINT[calIndex];
                    if(calIndex)
                        standWeight -= STAND_WEIGHT_POINT[calIndex - 1];
                    displayClrBuf(&DisplayData);
                    if(UserProcess.ProcessFlag.flagBit.UserCalib)
                        displayChar2Tuble(" PUT",DisplayData.numberDataLeft,sizeof(DisplayData.numberDataLeft));
                    else
                        displayChar2Tuble(" CEL",DisplayData.numberDataLeft,sizeof(DisplayData.numberDataLeft));
                    subAdc = userAdcStruct.DisplayAdc - ScaleWeight.ZeroPointADC;  
                    for(uint8_t i = 0; i < calIndex ; i++)
                        subAdc -= ScaleInfor.Calibration[i];
                    if(subAdc < (CAL_ADCSUB_MUL_MIN*standWeight) || (subAdc&0x80000000))
                    {
                        if(UserProcess.ProcessFlag.flagBit.DisplayFlash)
                            displayWeight(STAND_WEIGHT_POINT[calIndex],WEIGHT_UNIT_G);
                        if(userAdcStruct.Flag.Bit.lock && ScaleWeight.Flag.Bit.CalibrAtoZrEn)             //小重量锁定找零
                        {
                            ScaleWeight.ZeroPointADC = userAdcStruct.DisplayAdc;
                            ScaleWeight.TarePointADC = ScaleWeight.ZeroPointADC;
                        }
                    }else{
                        // if(!UserProcess.ProcessFlag.flagBit.UserCalib)
                        {
                            displayNumber2Number(subAdc>>6,0,DisplayData.numberDataMidle,sizeof(DisplayData.numberDataMidle));
                        }
                        if(userAdcStruct.Flag.Bit.lock)
                        {
                            ScaleInfor.Calibration[calIndex] = subAdc;
                            SwitchUserSubProcessNext();
                            if(UserProcess.ProcessFlag.flagBit.UserCalib)
                                SwitchUserSubProcess(D_CAL_Finish);
                        }
                    }            
                }
                break;
        case    D_CAL_Finish:
                {
                    if(!UserProcess.ProcessFlag.flagBit.Subrun)
                    {
                        UserProcess.ProcessFlag.flagBit.Subrun = true;
                        displayClrBuf(&DisplayData);
                        if(UserProcess.ProcessFlag.flagBit.UserCalib)
                        {
                            displayChar2Tuble(" PUT",DisplayData.numberDataLeft,sizeof(DisplayData.numberDataLeft));
                            for(uint8_t i = 1;i < CALIBRATE_PIONT;i++)
                            {
                                tempSubAdc = (STAND_WEIGHT_POINT[i] - STAND_WEIGHT_POINT[i-1]);
                                tempSubAdc *= ScaleInfor.Calibration[i-1];
                                if(i > 1)
                                    ScaleInfor.Calibration[i] = tempSubAdc / (STAND_WEIGHT_POINT[i - 1] - STAND_WEIGHT_POINT[i - 2]);
                                else
                                    ScaleInfor.Calibration[i] = tempSubAdc / (STAND_WEIGHT_POINT[i - 1] - 0);
                            }
                        }
                        else{
                            displayChar2Tuble(" CEL",DisplayData.numberDataLeft,sizeof(DisplayData.numberDataLeft));
                            if(!ScaleInfor.Calibration[CALIBRATE_PIONT - 1])                                        //自动补充标定
                            {
                                // ScaleInfor.Calibration[CALIBRATE_PIONT - 1] = ScaleInfor.Calibration[CALIBRATE_PIONT - 2]*(STAND_WEIGHT_POINT[CALIBRATE_PIONT - 2] - STAND_WEIGHT_POINT[CALIBRATE_PIONT - 3]);
                                tempSubAdc = (STAND_WEIGHT_POINT[CALIBRATE_PIONT - 1] - STAND_WEIGHT_POINT[CALIBRATE_PIONT - 2]);
                                tempSubAdc *= ScaleInfor.Calibration[CALIBRATE_PIONT - 2];
                                ScaleInfor.Calibration[CALIBRATE_PIONT - 1] = tempSubAdc / (STAND_WEIGHT_POINT[CALIBRATE_PIONT - 2] - STAND_WEIGHT_POINT[CALIBRATE_PIONT - 3]);
                            }
                        }
                        displayChar2Tuble(" PASS",DisplayData.numberDataMidle,sizeof(DisplayData.numberDataMidle));

                        coffeMacInfor.Mode = COFFE_HandleMode;          //<切回手动模式
                        coffeMacInfor.Flag.Bit.Change = true;           //>

                        ScaleInfor.Existflag = EXSIT_FLAG;
                        WriteScaleInfor(&ScaleInfor);
                        LOG("save Scale Infor:");
                        displayScaleInfor(&ScaleInfor);
                    }  
                    if(UserProcess.subProcessHalfSec > 4)
                    {
                        SwitchUseProcess(D_USER_PROCESS_ON);
                        InitScale();
                        InitCoffeeMac2PowerON();
                        // WriteCoffeeInfor(&coffeMacInfor);
                    }
                }
                break;
        default:
            break;
    }
}

void displayScaleInfor(Scale_data_t * scaleData)
{
    LOG("exsit flag = 0x%X\r\n",scaleData->Existflag);
    LOG("divison weight = %d\r\n",scaleData->DivisionWeight);
    for(uint8_t i = 0 ; i < CALIBRATE_PIONT;i++)
    {
        LOG("cal %d sub adc = 0x%X\r\n",i,scaleData->Calibration[i]);
    }
    LOG("max weight = %d\r\n",scaleData->MaxWeight);
    LOG("min weight = %d\r\n",scaleData->MinWeight);
    LOG("weight range index = %d\r\n",scaleData->WeightRangIndex);
    LOG("crc = 0x%X\r\n",scaleData->Crccheck_sum);
}


